home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Programmer Disk
/
The Programmer Disk (Microforum).iso
/
xpro
/
c4
/
pro13
/
maketre_.asm
< prev
next >
Wrap
Assembly Source File
|
1991-02-11
|
6KB
|
311 lines
;***********************************************
; maketree.asm -- makes Huffman tree
;***********************************************
page 0, 128
include amscls.inc
$_init GEN
TEXT segment byte public 'CODE'
TEXT ends
DATA segment word public 'DATA'
DATA ends
BSS segment word public 'DATA'
extrn right_:word
extrn left_:word
extrn nchar:word
extrn n2:word
extrn avail_mt:word
extrn heapsize:word
extrn freq:word
extrn sort:word
extrn bitlen:word
extrn code:word
extrn depth:word
extrn heap:word
extrn len_cnt:word
extrn start:word
extrn weight:word
BSS ends
DGROUP group DATA, BSS
TEXT segment byte public 'CODE'
assume cs:TEXT, ds:DGROUP
;---------------------------------------------------------------
; static void count_len(short i) /* call with i = root */
;
;---------------------------------------------------------------
public count_len
count_len proc near
$_if <cmp bx, n2>, B
mov bx, depth
$_if <cmp bx, 16 * 2>, A
mov bx, 16 * 2
$_endif
inc len_cnt[bx]
ret
$_endif
add depth, 2
push bx
mov bx, left_[bx]
call count_len
pop bx
push bx
mov bx, right_[bx]
call count_len
pop bx
shr left_[bx], 1
shr right_[bx], 1
sub depth, 2
ret
count_len endp
;---------------------------------------------------------------
; static void downheap(short i)
; bx
;---------------------------------------------------------------
public downheap
downheap proc near
push cx
push dx
push si
push di
push bp
mov si, heap[bx]
push si
mov bp, freq
mov cx, ds:[bp + si]
mov si, bx
$_while <TRUE>
shl si, 1
$_break , <cmp si, heapsize>, A
mov di, heap[si]
mov ax, ds:[bp + di]
$_if , B, AND
mov di, heap[si + 2]
mov dx, ds:[bp + di]
$_c <cmp ax, dx>, A
mov ax, dx
add si, 2
$_endif
$_break , <cmp cx, ax>, BE
mov di, heap[si]
mov heap[bx], di
mov bx, si
$_enddo
pop heap[bx]
pop bp
pop di
pop si
pop dx
pop cx
ret
downheap endp
;---------------------------------------------------------------
; short make_tree(short nparm, ushort freqparm[],
; cx bx
; uchar lenparm[], ushort codeparm[])
; di ax
;---------------------------------------------------------------
public make_tree_
make_tree_ proc near
push cx
push dx
push si
push di
push bp
mov nchar, ax
mov freq, bx
mov bitlen, cx
mov code, dx
shl ax, 1
mov n2, ax
mov avail_mt, ax
xor ax, ax
cld
push ds
pop es
mov di, cx
mov cx, nchar
rep stosb
mov cx, nchar
mov di, freq
lea dx, 2[di]
mov bx, offset DGROUP:heap
jmp make_tree_1
$_do
add bx, 2
mov [bx], di
sub [bx], dx
make_tree_1:
xor ax, ax ; set ZERO flag
$_until <repz scasw>, Z
sub bx, offset DGROUP:heap
mov heapsize, bx
$_if <cmp bx, 4>, B
mov ax, heap[2]
mov di, ax
add di, code
mov word ptr [di], 0
jmp return
$_endif
shr bx, 1
and bx, 0fffeh
$_do
push bx
call downheap
pop bx
$_until <sub bx, 2>, Z
mov di, code
$_do
mov si, heap[2]
$_if <cmp si, n2>, B
mov [di], si
add di, 2
$_endif
mov bx, heapsize
sub heapsize, 2
mov ax, heap[bx]
mov heap[2], ax
mov bx, 2
call downheap
mov dx, heap[2]
$_if <cmp dx, n2>, B
mov [di], dx
add di, 2
$_endif
mov bx, avail_mt
add avail_mt, 2
mov left_[bx], si
mov right_[bx], dx
mov heap[2], bx
mov bp, freq
mov ax, [si + bp]
mov si, dx
add ax, [si + bp]
mov dx, bx
add bx, bp
mov [bx], ax
mov bx, 2
call downheap
$_until <cmp heapsize, 2>, BE
mov bx, dx
push dx
;---------------------------------------------------------------
; static void make_len(short root)
;---------------------------------------------------------------
public make_len
make_len:
xor ax, ax
mov di, offset DGROUP:len_cnt
mov cx, 17
rep stosw
mov depth, ax
call count_len
xor dx, dx
mov cx, 15
mov si, offset DGROUP:len_cnt + 2
$_do
lodsw
shl ax, cl
add dx, ax
$_until <LOOP>
add dx, [si]
$_if , NZ
sub len_cnt[16 * 2], dx
mov cx, dx
$_do
mov di, offset DGROUP:len_cnt + 15 * 2
$_while <cmp word ptr [di], 0>, E
sub di, 2
$_enddo
dec word ptr [di]
add word ptr [di + 2], 2
$_until <LOOP>
$_endif
mov di, offset DGROUP:len_cnt + 16 * 2
mov si, code
mov al, 16
$_do
mov cx, [di]
jcxz make_len_1
$_do
mov bx, [si]
add si, 2
shr bx, 1
add bx, bitlen
mov [bx], al
$_until <LOOP>
make_len_1:
sub di, 2
dec al
$_until , Z
;---------------------------------------------------------------
; void make_code(short nchar, uchar bitlen[], ushort code[])
;---------------------------------------------------------------
public make_code
make_code:
xor ax, ax
;;;
mov start, ax
mov weight, ax
;;;
mov si, offset DGROUP:len_cnt + 2
mov di, offset DGROUP:start + 2
mov bx, offset DGROUP:weight + 2
mov cx, 16
$_do
stosw
mov dx, [si]
add si, 2
dec cx
shl dx, cl
add ax, dx
mov dx, 1
shl dx, cl
inc cx
mov [bx], dx
add bx, 2
$_until <LOOP>
xor bx, bx
mov cx, nchar
mov si, bitlen
mov di, code
$_do
lodsb
shl al, 1
mov bl, al
mov ax, start[bx]
stosw
mov ax, weight[bx]
add start[bx], ax
$_until <LOOP>
;---------------------------------------------------------------
pop ax
return:
shr ax, 1
pop bp
pop di
pop si
pop dx
pop cx
ret
make_tree_ endp
TEXT ends
end